﻿#region using
using AwesomeTanks.Sources.GameElements.MapElements;
using Microsoft.Xna.Framework;
using System;
#endregion

namespace AwesomeTanks.Sources.GameElements.Factories
{
    /// <summary>
    /// The factory of a Map. This class returns a Map with all her Walls and SpawnPoints
    /// </summary>
    public static class MapFactory
    {
        #region Fields
        public static Rectangle MAP_SIZE = new Rectangle((int)GameStateManagementGame.ScreenSize.X * 1 / 100, (int)GameStateManagementGame.ScreenSize.Y * 10 / 100, (int)GameStateManagementGame.ScreenSize.X * 98 / 100, (int)GameStateManagementGame.ScreenSize.Y * 89 / 100);
        public const int SIZE_BAILEY_WIDTH = 5;
        public const int SIZE_WALL = 50;
        public const int WIDTH_DESTRUCTIBLE_WALL = 5;
        public const int SIZE_SQUARE_WALL = 40;
        public static int INITIAL_DESTRUCTIBLE_WALL_LIFE = 100;
        #endregion

        /// <summary>
        /// Gets the map with the Specified number.
        /// </summary>
        /// <param name="nbmap">The nbmap.</param>
        /// <returns></returns>
        public static Map GetMap(int nbmap)
        {
            Map map = new Map();
            map.MapName = "Empty";
            //For now we always use the same Bailey's walls and the same Spawn Points
            GetBailey(map);
            GetSpawnPoint(map);

            int MiddleScreenX = MAP_SIZE.X + MAP_SIZE.Width / 2;
            int MiddleScreenY = MAP_SIZE.Y + MAP_SIZE.Height / 2;
            int StartSizeMapX = MAP_SIZE.X;
            int StartSizeMapY = MAP_SIZE.Y;
            int EndSizeMapX = MAP_SIZE.X + MAP_SIZE.Width;
            int EndSizeMapY = MAP_SIZE.Y + MAP_SIZE.Height;
            switch (nbmap)
            {
                case 1: //Cross Map
                    map.MapName = "Cross";
                    for (int i = StartSizeMapX + MAP_SIZE.Width / 4; i < EndSizeMapX - MAP_SIZE.Width / 4; i += SIZE_WALL)
                    {
                        map.AddWall(WallFactory.getWall(new Vector2(i, MiddleScreenY), SIZE_WALL, WIDTH_DESTRUCTIBLE_WALL, INITIAL_DESTRUCTIBLE_WALL_LIFE));
                    }
                    for (int j = StartSizeMapY + MAP_SIZE.Height / 4; j < EndSizeMapY - MAP_SIZE.Height / 4; j += SIZE_WALL)
                    {
                        map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX, j), WIDTH_DESTRUCTIBLE_WALL, SIZE_WALL, INITIAL_DESTRUCTIBLE_WALL_LIFE));
                    }
                    break;
                case 2: //Moria Map
                    map.MapName = "Moria";
                    for (int i = MiddleScreenX - MAP_SIZE.Width * 3 / 8 - SIZE_SQUARE_WALL / 2; i < MiddleScreenX + MAP_SIZE.Width * 3 / 8 + SIZE_SQUARE_WALL / 2; i += SIZE_SQUARE_WALL * 5)
                    {
                        for (int j = MiddleScreenY - MAP_SIZE.Height * 3 / 8 + SIZE_SQUARE_WALL / 2; j < MiddleScreenY + MAP_SIZE.Height * 3 / 8 + SIZE_SQUARE_WALL / 2; j += SIZE_SQUARE_WALL * 5)
                        {
                            map.AddWall(WallFactory.getWall(new Vector2(i, j), SIZE_SQUARE_WALL, SIZE_SQUARE_WALL, INITIAL_DESTRUCTIBLE_WALL_LIFE));
                        }
                    }
                    break;
                case 3: // Jarvan4 Map
                    map.MapName = "Jarvan";
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - MAP_SIZE.Height / 4, MiddleScreenY - MAP_SIZE.Height / 4), MAP_SIZE.Height / 2, WIDTH_DESTRUCTIBLE_WALL, INITIAL_DESTRUCTIBLE_WALL_LIFE));
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - MAP_SIZE.Height / 4, MiddleScreenY + MAP_SIZE.Height / 4), MAP_SIZE.Height / 2, WIDTH_DESTRUCTIBLE_WALL, INITIAL_DESTRUCTIBLE_WALL_LIFE));
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - MAP_SIZE.Height / 4, MiddleScreenY - MAP_SIZE.Height / 4), WIDTH_DESTRUCTIBLE_WALL, MAP_SIZE.Height / 2, INITIAL_DESTRUCTIBLE_WALL_LIFE));
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX + MAP_SIZE.Height / 4, MiddleScreenY - MAP_SIZE.Height / 4), WIDTH_DESTRUCTIBLE_WALL, MAP_SIZE.Height / 2 + WIDTH_DESTRUCTIBLE_WALL, INITIAL_DESTRUCTIBLE_WALL_LIFE));
                    break;
                case 4: // Koh Lanta Map
                    map.MapName = "Koh-Lanta";
                    int KohLantaBodyWidth = 200;
                    int KohLantaBodyHeight = 330;
                    int KohLantaHeadHeight = 180;
                    int KohLantaHeadWidth = 350;
                    int KohLantaArmSize = 270;
                    int KohLantaHandSize = 100;
                    int KohLantaLegAndArmWidth = 50;
                    int KohLantaLegSize = 270;
                    int KohLantaFootSize = 200;

                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - KohLantaBodyWidth / 2, MiddleScreenY - KohLantaBodyHeight / 2), KohLantaBodyWidth, KohLantaBodyHeight, INITIAL_DESTRUCTIBLE_WALL_LIFE)); // Body
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - KohLantaHeadWidth / 2, MiddleScreenY - KohLantaBodyHeight / 2 - KohLantaHeadHeight), KohLantaHeadWidth, KohLantaHeadHeight, INITIAL_DESTRUCTIBLE_WALL_LIFE));//head
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - KohLantaArmSize, MiddleScreenY - KohLantaLegAndArmWidth / 2), KohLantaArmSize, KohLantaLegAndArmWidth, INITIAL_DESTRUCTIBLE_WALL_LIFE));//Arm Left
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX, MiddleScreenY - KohLantaLegAndArmWidth / 2), KohLantaArmSize, KohLantaLegAndArmWidth, INITIAL_DESTRUCTIBLE_WALL_LIFE));//Arm Right
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - KohLantaLegSize, MiddleScreenY + KohLantaBodyHeight / 2), KohLantaLegSize, KohLantaLegAndArmWidth, INITIAL_DESTRUCTIBLE_WALL_LIFE));//Leg Left
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX, MiddleScreenY + KohLantaBodyHeight / 2), KohLantaLegSize, KohLantaLegAndArmWidth, INITIAL_DESTRUCTIBLE_WALL_LIFE));//Leg Right
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - KohLantaArmSize, MiddleScreenY - KohLantaHandSize), KohLantaLegAndArmWidth, KohLantaHandSize, INITIAL_DESTRUCTIBLE_WALL_LIFE));//Hand Left
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX + KohLantaArmSize - KohLantaLegAndArmWidth, MiddleScreenY - KohLantaHandSize), KohLantaLegAndArmWidth, KohLantaHandSize, INITIAL_DESTRUCTIBLE_WALL_LIFE));//Hand Right
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX - KohLantaLegSize, MiddleScreenY + KohLantaBodyHeight / 2), KohLantaLegAndArmWidth, KohLantaFootSize, INITIAL_DESTRUCTIBLE_WALL_LIFE));//Foot Left
                    map.AddWall(WallFactory.getWall(new Vector2(MiddleScreenX + KohLantaLegSize - KohLantaLegAndArmWidth, MiddleScreenY + KohLantaBodyHeight / 2), KohLantaLegAndArmWidth, KohLantaFootSize, INITIAL_DESTRUCTIBLE_WALL_LIFE));//Foot Right
                    break;
                case 5:
                    Random rand = new Random();
                    map= GetMap(rand.Next(0, 5));
                    break;
            }
            return map;
        }

        #region Methods
        /// <summary>
        /// Creates bailey's walls.
        /// </summary>
        /// <param name="map">The map.</param>
        public static void GetBailey(Map map)
        {
            int MiddleScreenX = MAP_SIZE.X + MAP_SIZE.Width / 2;
            int MiddleScreenY = MAP_SIZE.Y + MAP_SIZE.Height / 2;
            int StartSizeMapX = MAP_SIZE.X;
            int StartSizeMapY = MAP_SIZE.Y;
            int EndSizeMapX = MAP_SIZE.X + MAP_SIZE.Width;
            int EndSizeMapY = MAP_SIZE.Y + MAP_SIZE.Height;

            map.AddWall(WallFactory.getWall(new Vector2(StartSizeMapX, StartSizeMapY), MAP_SIZE.Width, SIZE_BAILEY_WIDTH));
            map.AddWall(WallFactory.getWall(new Vector2(StartSizeMapX, StartSizeMapY), SIZE_BAILEY_WIDTH, MAP_SIZE.Height));
            map.AddWall(WallFactory.getWall(new Vector2(StartSizeMapX, EndSizeMapY - SIZE_BAILEY_WIDTH), MAP_SIZE.Width, SIZE_BAILEY_WIDTH));
            map.AddWall(WallFactory.getWall(new Vector2(EndSizeMapX, StartSizeMapY), SIZE_BAILEY_WIDTH, MAP_SIZE.Height));
        }

        /// <summary>
        /// Creates spawn points.
        /// </summary>
        /// <param name="map">The map.</param>
        public static void GetSpawnPoint(Map map)
        {
            int StartSizeMapX = MAP_SIZE.X;
            int StartSizeMapY = MAP_SIZE.Y;
            int EndSizeMapX = MAP_SIZE.X + MAP_SIZE.Width;
            int EndSizeMapY = MAP_SIZE.Y + MAP_SIZE.Height;
            int MarginLeftRight = MAP_SIZE.Width * 3 / 100;
            int MarginTopBottom = MAP_SIZE.Height * 9 / 100;

            map.ListSpawn.Add(new SpawnPoint(new Vector2(StartSizeMapX + MarginLeftRight, StartSizeMapY + MarginTopBottom), PlayerIndex.One));
            map.ListSpawn.Add(new SpawnPoint(new Vector2(EndSizeMapX - MarginLeftRight, EndSizeMapY - MarginTopBottom), PlayerIndex.Two));
            map.ListSpawn.Add(new SpawnPoint(new Vector2(StartSizeMapX + MarginLeftRight, EndSizeMapY - MarginTopBottom), PlayerIndex.Three));
            map.ListSpawn.Add(new SpawnPoint(new Vector2(EndSizeMapX - MarginLeftRight, StartSizeMapY + MarginTopBottom), PlayerIndex.Four));
        }
        #endregion
    }

}
